package com.douqu.game.core.util;

import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.VipConfig;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.config.hegemony.HegemonyLvDifConfig;
import com.douqu.game.core.config.hegemony.HegemonySkillCountConfig;
import com.douqu.game.core.config.map.CityConfig;
import com.douqu.game.core.config.map.CityDropConfig;
import com.douqu.game.core.config.map.CityDropGroupConfig;
import com.douqu.game.core.config.task.GrowUpBoxConfig;
import com.douqu.game.core.e.E_CityDropBelong_Status;
import com.douqu.game.core.e.E_CityDrop_Flush_Type;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.ext.TaskInfo;
import com.douqu.game.core.entity.ext.data.challenge.WorldMapBeKillBean;
import com.douqu.game.core.entity.world.map.CityBean;
import com.douqu.game.core.entity.world.map.CityDropBean;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMapProto;

import java.util.*;

/**
 * @author: miracle.
 * Description: 大地图utils
 * Date: 2018/7/4 0004 下午 3:09
 * Huan Yu Copyright (c) 2017 All Rights Reserved.
 */
public class MapUtils {


    public static final long ONT_SECOND = 1000;//1000

    public static final int DROP_ADD_SECOND = 0;//每次计算掉落时间是否达到时增加0秒来计算

    public static final int ONE_HUNDRED = 100;

    /**
     * 获取当前掉落的 group config
     * 1.根据类型 判断当前值是否触发
     * 2.如果触发 找到对应的config
     * @param type
     * @param values
     * @return
     */
    public static CityDropGroupConfig getDropGroupConfig(E_CityDrop_Flush_Type type,long... values){

        List<CityDropGroupConfig> configList = getDropGroupConfigType(type);

        if (type == E_CityDrop_Flush_Type.CITY_DROP_FLUSH_EVEBKILL && values.length > 0){
            //连杀
            for (CityDropGroupConfig config:configList){
                if (config.killSubType == values[0]){
                    return config;
                }
            }
        }
        return null;
    }

    public static List<CityDropGroupConfig> getDropGroupConfigType(E_CityDrop_Flush_Type type){
        List<CityDropGroupConfig> allList = DataFactory.getInstance().getDataList(DataFactory.CITY_DROP_GROUP);
        List<CityDropGroupConfig> configList = new ArrayList<>();

        for (CityDropGroupConfig config:allList){
            if (config.type == type.getCode()){
                configList.add(config);
            }
        }
        return configList;
    }


    /**
     * 不归属于全局玩家的城市掉落奖励
     * @param cityDropConfigMap
     * @param weightCityMap
     * @param groupConfig
     * @param campType
     * @return
     */
    public static List<CityBean> getCanUseCity(Map<Integer, List<CityDropConfig>> cityDropConfigMap,Map<Integer, List<CityBean>> weightCityMap, CityDropGroupConfig groupConfig,SGCommonProto.E_CAMP_TYPE campType,String index){
        /**
         * 两种情况：1.如果城市小于等于奖励数 所有城市发放一份 不够的不给 2.如果城市数量大于奖励数 随机城市发放
         *
         */
        List<CityBean> cityBeanList = null;
        Random random = new Random();
        CityDropConfig dropConfig = null;
        CityBean cityBean1 = null;
        List<CityBean> getDropCityList = new ArrayList<>();
        List<CityDropConfig> getCityDropList = new ArrayList<>();
        int limitCount = 0;
        for (Map.Entry<Integer, List<CityDropConfig>> entry:cityDropConfigMap.entrySet()){
            //判断城市数量够不够
            if ((cityBeanList = weightCityMap.get(entry.getKey())) != null){
                //第一种情况
                //如果有一个list为空 continue
                if (cityBeanList.size() == 0 || entry.getValue().size() == 0)
                    continue;

                if (cityBeanList.size() <= entry.getValue().size()){
                    //城市数量少就遍历城市发放奖励
                    for (CityBean cityBean:cityBeanList){
                        limitCount = 0;
                        while (true){
                            //如果循环10次都找不到这个奖励 则放弃
                            if (limitCount > Byte.MAX_VALUE)
                                break;
                            if (!getCityDropList.contains(dropConfig = entry.getValue().get(random.nextInt(entry.getValue().size())))){
                                //如果这个城市本次没有发放过奖励 添加奖励
                                if (groupConfig.visibleType == E_CityDropBelong_Status.CITY_DROP_PERSON.getCode()){
                                    cityBean.getCityDropData().getPlayerDropMap().put(index,new CityDropBean(dropConfig.id,groupConfig.rewardGroupId,DataFactory.currentTime,campType.getNumber()));
                                }else{
                                    cityBean.getCityDropData().getCampDropMap().put(campType.getNumber(), new CityDropBean(dropConfig.id,groupConfig.rewardGroupId,DataFactory.currentTime,campType.getNumber()));
                                }
                                getDropCityList.add(cityBean);
                                getCityDropList.add(dropConfig);
                                break;
                            }
                            limitCount ++;
                        }
                    }
                }else{
                    //第二种情况 遍历所有的奖励 然后随机一个城市进行发送
                    for (CityDropConfig cityDropConfig: entry.getValue()){
                        limitCount = 0;
                        while (true){
                            if (limitCount > Byte.MAX_VALUE)
                                break;
                            if(!getDropCityList.contains(cityBean1 = cityBeanList.get(random.nextInt(cityBeanList.size())))){
                                //如果这个城市本次没有发放过奖励 添加奖励
                                if (groupConfig.visibleType == E_CityDropBelong_Status.CITY_DROP_PERSON.getCode()){
                                    cityBean1.getCityDropData().getPlayerDropMap().put(index,new CityDropBean(cityDropConfig.id,groupConfig.rewardGroupId,DataFactory.currentTime,campType.getNumber()));
                                }else{
                                    cityBean1.getCityDropData().getCampDropMap().put(campType.getNumber(), new CityDropBean(cityDropConfig.id,groupConfig.rewardGroupId,DataFactory.currentTime,campType.getNumber()));
                                }
                                getDropCityList.add(cityBean1);
                                getCityDropList.add(cityDropConfig);
                                break;
                            }
                            limitCount ++;
                        }
                    }
                }
            }
        }
        return getDropCityList;
    }

    /**
     * 获取归属于全局玩家的奖励城市
     * @param cityDropConfigMap
     * @param cityMap
     * @param groupConfig
     * @return
     */
    public static List<CityBean> getCanUseCity(Map<Integer, List<CityDropConfig>> cityDropConfigMap,Map<Integer, CityBean> cityMap,CityDropGroupConfig groupConfig){
        List<CityBean> cityBeanList = new ArrayList<>();
        List<CityBean> cityList = new ArrayList<>();
        /**
         * 这里分两个循环做 先求出可以直接加掉落奖励的城市
         * 如果在一个循环做 第二个循环要做大量的随机操作可能会影响性能
         */
        CityDropBean allDrop = null;
        CityDropGroupConfig cityDropGroupConfig = null;
        for (CityBean bean:cityMap.values()){
            if (bean.getConfig().type == SGCommonProto.E_CITY_TYPE.CITY_TYPE_CAPITAL_VALUE){
                continue;
            }
            allDrop = bean.getCityDropData().getAllDrop();
            if (allDrop == null || allDrop.getDropGroup() == 0
                    || (cityDropGroupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, allDrop.getDropGroup())) == null
                    || getSeconds(allDrop.getDropTime() + keepTime(cityDropGroupConfig.aliveTime)) <= 0) {
                    cityList.add(bean);
            }
        }
        Random random = new Random();
        CityBean cityBean = null;
        if (cityList.size() == 0){
            return cityBeanList;
        }
        for (List<CityDropConfig> value:cityDropConfigMap.values()){
            for (CityDropConfig config:value){
                int limitCount = 0;
                while (limitCount < Byte.MAX_VALUE){

                    if(!cityBeanList.contains(cityBean = cityList.get(random.nextInt(cityList.size())))){
                        cityBean.getCityDropData().setAllDrop(new CityDropBean(config.id,groupConfig.rewardGroupId,DataFactory.currentTime,0));
                        cityBeanList.add(cityBean);
                        break;
                    }
                    limitCount ++;
                }
            }
        }
        return cityBeanList;
    }

    /**
     * 根据权重获取掉落信息
     * @param groupConfig
     * @return
     */
    public static Map<Integer,List<CityDropConfig>> getCityDropMap(CityDropGroupConfig groupConfig,Map<Integer,Integer> cityMap){
        Map<Integer,List<CityDropConfig>> map = new HashMap<>();
        TwoTuple<Integer,List<CityDropConfig>> twoTuple = getCityDorpListByGroup(groupConfig.rewardGroupId);
        Random random = new Random();
        List<CityDropConfig> weightList = null;
        int count = 0;
        int loopTime = 0;
        Map<Integer,Integer> useWeightMap = new HashMap<>();
        while (true){
            loopTime ++;
            if (loopTime >= Byte.MAX_VALUE)
                break;
            int sum = 0;
            int weight = random.nextInt(twoTuple.getFirst());
            for (CityDropConfig config: twoTuple.getSecond()){
                if (sum <= weight
                        && weight < sum + config.probabilityWeight){

                    //如果没有可用的城市取其他的城市
                    int weightCount = cityMap.get(config.campWeight) == null ? 0:cityMap.get(config.campWeight);
                    int uerWeightCount = useWeightMap.get(config.campWeight) == null ? 0:useWeightMap.get(config.campWeight);
                    if (uerWeightCount >= weightCount){
                        //不随机这种城市
                        continue;
                    }
                    /**
                     * 判断阵营权重
                     */
                    if ((weightList = map.get(config.campWeight)) == null){
                        weightList = new ArrayList<>();
                        map.put(config.campWeight,weightList);
                    }
                    //可以重复奖励
                    weightList.add(config);
                    useWeightMap.merge(config.campWeight,1,(v1,v2)->v1 + v2);
                    if (++count == groupConfig.count)
                        break;
                }
                sum += config.probabilityWeight;
            }
            if (count == groupConfig.count)
                break;
        }
        return map;
    }

    public static Map<Integer,List<CityDropConfig>> getCityDropMap(CityDropGroupConfig groupConfig){
        Map<Integer,List<CityDropConfig>> map = new HashMap<>();
        TwoTuple<Integer,List<CityDropConfig>> twoTuple = getCityDorpListByGroup(groupConfig.rewardGroupId);
        Random random = new Random();
        List<CityDropConfig> weightList = null;
        int count = 0;
        int loopTime = 0;
        while (true){
            loopTime ++;
            if (loopTime >= Byte.MAX_VALUE)
                break;
            int sum = 0;
            int weight = random.nextInt(twoTuple.getFirst());
            for (CityDropConfig config: twoTuple.getSecond()){
                if (sum <= weight
                        && weight < sum + config.probabilityWeight){
                    /**
                     * 判断阵营权重
                     */
                    if ((weightList = map.get(config.campWeight)) == null){
                        weightList = new ArrayList<>();
                        map.put(config.campWeight,weightList);
                    }
                    //可以重复奖励
                    weightList.add(config);
                    if (++count == groupConfig.count)
                        break;
                }
                sum += config.probabilityWeight;
            }
            if (count == groupConfig.count)
                break;
        }
        return map;
    }

    /**
     * 获取通知城市掉落的response
     * @param changeList
     * @param groupConfig
     * @param campType
     * @param index
     * @return
     */
    public static SGMapProto.S2C_HegemonyCityDrop.Builder getSendCityDropResponse(List<CityBean> changeList,CityDropGroupConfig groupConfig,SGCommonProto.E_CAMP_TYPE campType,String index){
        //通知玩家变化城市掉落
        SGMapProto.S2C_HegemonyCityDrop.Builder response = SGMapProto.S2C_HegemonyCityDrop.newBuilder();
        SGCommonProto.CityDrop.Builder cityDrop;
        CityDropBean dropBean = null;
        CityDropGroupConfig cityDropGroupConfig = null;
        for (CityBean cityBean:changeList){
            /**
             * 1.如果归属所有的显示
             * 2.如果归属阵营 没有所有的显示 有则不显示
             * 3.如果归属个人 没有所有的阵营的显示 有则不显示
             */
            cityDrop = SGCommonProto.CityDrop.newBuilder();

            if (groupConfig.visibleType == E_CityDropBelong_Status.CITY_DROP_ALL.getCode()){
                cityDrop.setCityId(cityBean.id);
                cityDrop.setConfigId(cityBean.getCityDropData().getAllDrop().getRewardId());
                cityDrop.setRemainTime(groupConfig.aliveTime * ONT_SECOND);
                response.addDropList(cityDrop);
            } else {
                //验证全局奖励是否过期 未过期continue
                dropBean = cityBean.getCityDropData().getAllDrop();
                if (dropBean != null && (cityDropGroupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, dropBean.getDropGroup())) != null && MapUtils.getSeconds(dropBean.getDropTime() + MapUtils.keepTime(cityDropGroupConfig.aliveTime)) > 0){
                    continue;
                }
                if (groupConfig.visibleType == E_CityDropBelong_Status.CITY_DROP_POWER.getCode()){
                    cityDrop.setCityId(cityBean.id);
                    cityDrop.setConfigId(cityBean.getCityDropData().getCampDropMap().get(campType.getNumber()).getRewardId());
                    cityDrop.setRemainTime(groupConfig.aliveTime * ONT_SECOND);
                    response.addDropList(cityDrop);
                }else{
                    dropBean = cityBean.getCityDropData().getCampDropMap().get(campType.getNumber());
                    if (dropBean != null && (cityDropGroupConfig = DataFactory.getInstance().getGameObject(DataFactory.CITY_DROP_GROUP, dropBean.getDropGroup())) != null && MapUtils.getSeconds(dropBean.getDropTime() + MapUtils.keepTime(cityDropGroupConfig.aliveTime)) > 0){
                        continue;
                    }
                    if (groupConfig.visibleType == E_CityDropBelong_Status.CITY_DROP_PERSON.getCode()){
                        cityDrop.setCityId(cityBean.id);
                        cityDrop.setConfigId(cityBean.getCityDropData().getPlayerDropMap().get(index).getRewardId());
                        cityDrop.setRemainTime(groupConfig.aliveTime * ONT_SECOND);
                        response.addDropList(cityDrop);
                    }
                }
            }
        }
        return response;
    }

    public static TwoTuple<Integer,List<CityDropConfig>> getCityDorpListByGroup(int group){
        //先判断阵营有什么样子的城 以及个数
        TwoTuple<Integer,List<CityDropConfig>> twoTuple = new TwoTuple<>();
        List<CityDropConfig> dropConfigList = new ArrayList<>();
        List<CityDropConfig> list = DataFactory.getInstance().getDataList(DataFactory.CITY_DROP);
        int sum = 0;
        for (CityDropConfig config:list){
            if (config.groupId == group){
                dropConfigList.add(config);
                sum += config.probabilityWeight;
            }
        }
        twoTuple.setFirst(sum);
        twoTuple.setSecond(dropConfigList);
        return twoTuple;
    }


    /**
     * 掉落持续时间
     * @param groupKeepTime
     * @return
     */
    public static long keepTime(int groupKeepTime){
        return (groupKeepTime + DROP_ADD_SECOND) * ONT_SECOND;
    }

    /**
     * 获取击杀基础分
     * @param skillCount
     * @return
     */
    public static int getBaseScore(int skillCount,boolean npc){
        HegemonySkillCountConfig skillCountConfig = HegemonySkillCountConfig.getByCount(skillCount);
        if (npc)
            return skillCountConfig.npcScore;
        return skillCountConfig.score;
    }

    /**
     * 获取当前倍率
     * @param player
     * @return
     */
    public static int getMulRate(Player player){
        TaskInfo taskInfo = player.getExtInfo(TaskInfo.class);
        List<GrowUpBoxConfig> growUpBoxConfigs = DataFactory.getInstance().getDataList(DataFactory.GROW_UP_BOX_KEY);
        int max = 1;
        GrowUpBoxConfig box;
        for (int i = 0; i < growUpBoxConfigs.size(); i++){
            box = growUpBoxConfigs.get(i);
            if (taskInfo.currentGrowthValue >= box.growthValue){
                if (i + 1 < growUpBoxConfigs.size() ){
                   max = growUpBoxConfigs.get(i + 1).hegemonyScore > max ? growUpBoxConfigs.get(i + 1).hegemonyScore:max;
                }else{
                    max = box.hegemonyScore;
                }
            }
        }
        return max;
    }

    /**
     * 获取等级差倍率
     * @param dif
     * @return
     */
    public static int getLvDifMulRate(int dif){
        return HegemonyLvDifConfig.getMultiple(dif);
    }

    /**
     * 重复击杀倍率
     * @param number
     * @return
     */
    public static int getRepeatMulRate(int number){
        StableDataConfig repeatConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.HEGEMONY_REPEAT_PLAYER_MUL.getCode());
        return repeatConfig.getRepeatMul(number);
    }

    /**
     * 获取vip等级倍率
     * @param player
     * @return
     */
    public static int getVipMulRate(Player player){
        VipConfig vipConfig = DataFactory.getInstance().getGameObject(DataFactory.VIP_KEY, player.getVipLevel());
        return vipConfig.hegemonyMul;//vip倍率
    }

    /**
     * 获取诛杀得分
     * @param beKillBean
     * @return
     */
    public static int getKillAndKillScore(WorldMapBeKillBean beKillBean){
        StableDataConfig skillConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,E_StableDataType.HEGEMONY_KILLANDKILL_VALUE.getCode());
        int skillScore = 0;
        for (CommonData commonData:skillConfig.commons){
            if (commonData.id <= beKillBean.getBeKillCount() && skillScore < commonData.value)
                skillScore = commonData.value;
        }
        return skillScore;
    }

    /**
     * 获取城市得分
     * @return
     */
    public static int getCityScore(SGCommonProto.E_CITY_TYPE cityType){
        StableDataConfig cityConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,E_StableDataType.HEGEMONY_CITY_VALUE.getCode());
        for (CommonData commonData:cityConfig.commons){
            if (commonData.id == cityType.getNumber())
                return commonData.value;
        }
        return 0;
    }

    /**
     * 获取到现在的秒数
     * @param time
     * @return
     */
    public static int getSeconds(long time){
        return (int)((time - DataFactory.currentTime)/ONT_SECOND);
    }

    public static long getMilliBySeconds(int seconds){
        return ONT_SECOND * seconds;
    }

    public static long getMilliBySeconds(long seconds){
        return ONT_SECOND * seconds;
    }
}
